#include "sharertos.h"

//初始化任务堆栈,指针函数返回一个os_u32的指针
/********************************************
taskcallback:传入的任务函数
p_arg:       任务的参数
p_stk_base   任务的堆栈起始地址
stk_size:    任务的栈大小
*********************************************/
os_u32	*os_taskstkinit(taskfun taskcallback,void *p_arg,os_u32 *p_stk_base,os_u32 stk_size)
{
   os_u32   *p_stktop;
   //stm32的栈时向下生长
   //获取栈顶
   p_stktop         =   &p_stk_base[stk_size];
   //将堆栈8-bytes对齐
   //p_stktop         =  (os_u32*)((os_u32)(p_stktop) & 0xfffffff8u);
   //异常发生时自动保存的寄存器
    //xpsr 的第24位写1防止产生 invstate 异常
    *--p_stktop =  (os_u32)0x01000000u;  //xpsr 寄存器
    *--p_stktop =  (os_u32)taskcallback;       //r15(pc)任务的入口地址
    *--p_stktop =  (os_u32)0x14141414u;  //r14(lr)
    *--p_stktop =  (os_u32)0x12121212u;  //r12
    *--p_stktop =  (os_u32)0x03030303u;  //r3
    *--p_stktop =  (os_u32)0x02020202u;  //r2
    *--p_stktop =  (os_u32)0x01010101u;  //r1
    *--p_stktop =  (os_u32)p_arg;        //r0 任务形参

    /*异常需要手动保存的参数*/
    *--p_stktop =  (os_u32)0x11111111u;  //r11
    *--p_stktop =  (os_u32)0x10101010u;  //r10
    *--p_stktop =  (os_u32)0x09090909u;  //r9
    *--p_stktop =  (os_u32)0x08080808u;  //r8
    *--p_stktop =  (os_u32)0x07070707u;  //r7
    *--p_stktop =  (os_u32)0x06060606u;  //r6
    *--p_stktop =  (os_u32)0x05050505u;  //r5
    *--p_stktop =  (os_u32)0x04040404u;  //r4
    return p_stktop;
}


/*
任务切换函数
*/
void os_tasksched(void)
{
	if(ostcbcurptr == &u_tcb1)
	{
		ostcbhighrdyptr = &u_tcb2;
	}
	else
	{
		ostcbhighrdyptr = &u_tcb1;
	}
	sharertos_triggerpendsv();
}

/*
任务控制块初始化函数
*/
void os_tasktcbinit(os_tcb *p_tcb)
{
	//将全部变量清空
	p_tcb->stkptr		= (os_u32*)0;
	p_tcb->taskname		= (os_i8*)0;
	p_tcb->taskprio		= (os_u32)0;
	p_tcb->tcb_next		= (os_tcb*)0;
	p_tcb->tcb_prev		= (os_tcb*)0;
}

//创建任务,暂时不支持内存管理，使用静态放到进行创建
//任务控制块
//创建任务的函数
//任务运行时传入的参数
//任务的名称
//任务的优先级
//任务的堆栈地址
//堆栈大小
//错误码
void ostaskcreatestatic(os_tcb* p_tcb,taskfun taskfun,void *p_arg,os_i8 *taskname,os_u32 prio,os_u32 *p_stk_base,os_u32 stk_size)
{
    os_u32 *taskinitret;
    os_tasktcbinit(p_tcb);
    taskinitret = os_taskstkinit(taskfun,p_arg,p_stk_base,stk_size);
    //防止编译警告
    p_tcb->stkptr = taskinitret;
    p_tcb->taskname = taskname;
    p_tcb->taskprio = prio; 
    //插入就绪表
    //os_rdylistinsert(p_tcb);
    //*err = os_err_none;
}

/***************************************
系统开始运行
***************************************/
void osstart(void)
{
	ostcbhighrdyptr		= &u_tcb1;
	sharertos_startrun();
}
